package Sampling;

import java.util.ArrayList;

import Definitions.GraphClass;
import Global.ConstantVariable;
import Global.GlobalClass;

/*****************************************************************
* Name : RandomSampling
* Aim  : This class is responsible for the random sampling operations with k-fold *
*****************************************************************/
public class RandomSamplingClass extends SamplingAbstractClass
{
	/*Keeps the fold order, at the begining it is set to 0 in constructor*/
	int maxFoldNumber;
	int orderOfFold;	
    int numberOfVal;
    int numberOfTest;
    int size;
    ArrayList<Integer> nodeList;   
    
	

	public int getOrderOfFold() {
		return orderOfFold;
	}

	public void setOrderOfFold(int orderOfFold) {
		this.orderOfFold = orderOfFold;
	}

	public double getTestRatio() {
		return testRatio;
	}

	public void setTestRatio(double testRatio) {
		this.testRatio = testRatio;
	}

	public double getValRatio() {
		return valRatio;
	}

	public void setValRatio(double valRatio) {
		this.valRatio = valRatio;
	}

    /*****************************************************************
	* Name : RandomSampling
	* Aim : This method is the constructor method and sets the attributes of the class*
	* Inputs : double testRatio, double valRatio, Graph g *
	* Outputs : - *
	* Data Structures : *
	* Algorithms :  *
	*****************************************************************/

	public RandomSamplingClass(GraphClass g, GlobalClass global,  double testRatio, double valRatio, double unusedRatio , double trainRatio)
	{
		super(g, global, testRatio, valRatio, unusedRatio, trainRatio);
		int seed=ConstantVariable.Common_ConstantVariables.SEED; // to get the same result seed must be defined
	    
		maxFoldNumber= (int) (1/ testRatio);
	    this.orderOfFold = 0;
	    this.size = g.getDataSet().size();
		numberOfTest = (int) (testRatio * size);
		numberOfVal = (int) (valRatio * size);
	    nodeList = new ArrayList<Integer>();
	
	    for (int i = 0; i < size; i++)
		{
			int m = i;
			nodeList.add(i, m);
		}
		shuffle(nodeList, seed);
		this.name ="Random Sampling";
	}
	
	/*****************************************************************
	* Name : Set
	* Aim : The aim of this method is putting nodes to train, val and test clusters 
	* with respect to test and val ratios*
	* Inputs : Graph g *
	* Outputs : - *
	* Data Structures : *
	* Algorithms : for the first fold it will work like that : test(%10) - val(%10) - train(%80)
	* 				for the second fold : train(%10) - test(%10) - val(%10) - train (%70)
	* 				for given test ratio : %10 and val ratio : %10 *
	*****************************************************************/
	public void generateSampling(GraphClass g)
	{
		int graphSize = g.getDataSet().size();
		int j;
		int m;
		/*Assigning nodes as test, starting from the numberOfTest * orderOfFold in the nodeList*/
		for (j = (numberOfTest * orderOfFold)%graphSize, m = 0; m < numberOfTest; m++, j = (j+1)%graphSize )
		{
			addNodeToTestSet(g.getDataSet().get(nodeList.get(j)));
		}

		for(m=0; m<numberOfVal; m++, j = (j+1)%graphSize)
		{
			addNodeToValidationSet(g.getDataSet().get(nodeList.get(j)));
		}
		
		int unused = (int) (this.unusedRatio * graphSize);
		
		for(m=0; m<unused; j = (j+1)%graphSize, m++) 
		{
			addNodeToUnusedSet(g.getDataSet().get(nodeList.get(j)));
		}
		int trainSize = (int) (trainRatio* graphSize);
		
		for(m=0; m<trainSize; j = (j+1)%graphSize, m++) 
		{
			addNodeToTrainingSet(g.getDataSet().get(nodeList.get(j)));
		}
		/*Assign the rest of the nodes as val or train*/
		trainSize = getTrainAndValNodes().size();
		int testSize = getTestNodes().size();
		
		if(orderOfFold<maxFoldNumber-1)
			orderOfFold++;
	}
	
	public void generateSampling(GraphClass g, int foldNumber)
	{
		if(orderOfFold <0 && orderOfFold >maxFoldNumber)
		{
			System.out.print("error orderOfFold is not suitable parametre");
		}
		else
		{
			orderOfFold=foldNumber;
			generateSampling(g);
		}
	}	

	
	public void Print()
	{
		System.out.println(" nodeList:: ");
		for(int i=0; i< size; i++)
			System.out.print(" * "+nodeList.get(i));
		
		
	}
}
